#include <jni.h>

#include <sys/unistd.h>
#include "system/sysinfo.h"
#include "tcpserver/tcpserver.h"

#include "log.h"
#include "timer/timer.h"

class Tcpserver tcpserver;
class SysInfo sysInfo;

double get_wall_time()
{
    struct timeval time ;
    if (gettimeofday(&time,NULL)){
        return 0;
    }
    return ((double)time.tv_sec + (double)time.tv_usec * 0.000001)*1000.0;
}
// Write C++ code here.
//
// Do not forget to dynamically load the C++ library into your application.
//
// For instance,
//
// In MainActivity.java:
//    static {
//       System.loadLibrary("myapplication");
//    }
//
// Or, in MainActivity.kt:
//    companion object {
//      init {
//         System.loadLibrary("myapplication")
//      }
//    }
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_myapplication_control_SystemInfo_getSysInfo(JNIEnv *env, jobject thiz) {
    // TODO: implement getSysInfo()
    jstring str = nullptr;
    char txt[512];
    if (sysInfo.update()){
        sprintf(txt,"剩余内存:%lubyte\n "
                    "总内存:%lubyte\n"
                    "运行时间:%lus\n"
                    "1分钟:%lu\n"
                    "5分钟:%lu\n"
                    "15分钟:%lu\n"
                    "交换分区:%f\n"
                    "剩余交换分区:%f\n"
                    "缓存:%f\n"
                    "进程数:%d\n"
                    "pad:%d"
                    ,

                sysInfo.getFreeRam(),
                sysInfo.getTotalRam(),
                sysInfo.getUpTime(),
                sysInfo.getLoad1(),
                sysInfo.getLoad5(),
                sysInfo.getLoad15(),
                sysInfo.getTotalSwap() / 1024.0 / 1024 / 1024,
                sysInfo.getFreeSwap() / 1024.0 / 1024 / 1024,
                sysInfo.getBufferRam() / 1024.0 / 1024 / 1024,
                sysInfo.getProcs(),
                sysInfo.getPad()
                );
    }
    return env->NewStringUTF(txt);
}

extern "C"
JNIEXPORT jint JNICALL
Java_com_example_myapplication_control_SystemInfo_initServer(JNIEnv *env, jobject thiz, jstring ip,
                                                             jint port) {
    // TODO: implement initServer()
    const char * ipStr = env->GetStringUTFChars(ip, nullptr);
    return tcpserver.init(ipStr,port);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_control_SystemInfo_closeServer(JNIEnv *env, jobject thiz) {
    // TODO: implement closeServer()
    tcpserver.unInit();
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_myapplication_control_SystemInfo_write(JNIEnv *env, jobject thiz, jstring string) {
    // TODO: implement write()
    const char * str = env->GetStringUTFChars(string, nullptr);
    int size = env->GetStringUTFLength(string);
    return tcpserver.writeData(str,size);
}
#include <thread>
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_control_SystemInfo_delayTest(JNIEnv *env, jobject thiz) {
    // TODO: implement delayTest()

//
//    usleep(1000*1000*1000);
//    LOGD("delay:%f",time.elapsed());
    LOGD("1");

    std::thread t([=](){
        Timer time;
        double s;
        double e;
        for (int i = 0; i < 100; ++i) {
            time.restart();
            e = get_wall_time();
            usleep(i * 1000 * 500);
            s = get_wall_time();
            LOGD("%f %f",s - e ,time.elapsed());
        }
    });
    t.detach();

//    long e = std::clock();
//    LOGD("%lu,%lu,%lu",s,e,e-s);
}